//
// Created by miaomiaole on 2024/1/21.
//

#include <opencv2\opencv.hpp>

#include <iostream>
#include <opencv2\imgproc\types_c.h> //for CV_RGB2GRAY
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>

void create_ellipse();

using namespace cv;

using namespace std;

void DrawEllipse(Mat img, double angle) {
    int thickness = 4;
    int lineType = 10;
    ellipse(img, Point(600 / 2, 600 / 2),
            Size(600 / 4, 600 / 16), angle, 0, 360, Scalar(255, 129, 0),
            thickness, lineType);
}

void DrawFi1ledCirc1e(Mat img, Point center) {
    int thickness = 4;
    int lineType = 10;

    circle(img, center, 600 / 32, Scalar(155, 220, 220), thickness, lineType);
}

void create_ellipse_2() {
    Mat atomImage = Mat::zeros(600, 600, CV_8UC3);
    Mat rookImage = Mat::zeros(600, 600, CV_8UC3);

    DrawEllipse(atomImage, 90);
    DrawEllipse(atomImage, 0);
    DrawEllipse(atomImage, 45);
    DrawEllipse(atomImage, -45);
    DrawFi1ledCirc1e(atomImage, Point(300, 300));
    imshow("DrawEllipse", atomImage);
    waitKey(0);
};

void show_hsv() {
    auto cat = imread("./picture_1663037518439.jpeg");
    namedWindow("cat", WINDOW_AUTOSIZE);

    imshow("cat", cat);

    Mat gray_cat;
    //二值图
    cvtColor(cat, gray_cat, CV_RGB2GRAY);
    namedWindow("gray_cat", WINDOW_AUTOSIZE);
    imshow("gray_cat", gray_cat);

    // HSV图
    Mat hsv_cat;
    cvtColor(cat, hsv_cat, COLOR_RGB2HSV);
    namedWindow("hsv_cat", WINDOW_AUTOSIZE);
    imshow("hsv_cat", hsv_cat);

    waitKey(0);
}

void create_ten() {
    auto ten_imgs = (Mat) Mat::zeros(120, 120, CV_8UC3);

    // 对称
    auto rect_1 = Rect(10, 30, 60, 20);
    // 对称
    auto rect_2 = Rect(30, 10, 20, 60);

    rectangle(ten_imgs, rect_1, Scalar(0, 0, 253), -1, 8, 0);
    rectangle(ten_imgs, rect_2, Scalar(0, 0, 253), -1, 8, 0);

    rectangle(ten_imgs, Point(10, 30), Point(70, 50), Scalar(0, 255, 255), 2, 8, 0);
    rectangle(ten_imgs, Point(30, 10), Point(50, 70), Scalar(0, 255, 255), 2, 8, 0);
    rectangle(ten_imgs, Point(30, 30), Point(50, 50), Scalar(0, 0, 255), 3, 8);

    imshow("ten_imgs", ten_imgs);

    imwrite("./audisign.jpeg", ten_imgs);

    waitKey(0);
}


void create_audi_imgs() {
    Mat image2 = Mat::zeros(500, 850, CV_8UC3);

    circle(image2, Point(447, 63), 63, Scalar(52, 17, 255), -1);
    circle(image2, Point(200, 300), 100, Scalar(180, 178, 172), 7, 30);
    circle(image2, Point(350, 300), 100, Scalar(180, 178, 172), 7, 30);
    circle(image2, Point(500, 300), 100, Scalar(180, 178, 172), 7, 30);
    circle(image2, Point(650, 300), 100, Scalar(180, 178, 172), 7, 30);

    imshow("audi sign", image2);

    imwrite("./audisign.jpeg", image2);

    waitKey(0);

}

void create_text() {
    string text = "hello world";
    int fontFace = FONT_HERSHEY_PLAIN;
    double fontScale = 3;
    int thickness = 1;

    Mat img(600, 800, CV_8UC3, Scalar::all(0));

    int baseline = 0;

    Size textSize = getTextSize(text, fontFace, fontScale, thickness, &baseline);

    baseline += thickness;

    Point textOrg((img.cols - textSize.width) / 2, (img.rows - textSize.height) / 2);

    rectangle(img, textOrg + Point(0, baseline), textOrg + Point(textSize.width, -textSize.height), Scalar(0, 0, 255));

    putText(img, text, textOrg, fontFace, fontScale, Scalar::all(255), thickness, 8);

    imshow("hello", img);

    waitKey(0);

}


int Drawing_Random_Lines(Mat image, char *window_name, RNG rng);

int Drawing_Random_Rectangles(Mat image, char *window_name, RNG rng);

int Drawing_Random_Ellipses(Mat image, char *window_name, RNG rng);

int Drawing_Random_Polylines(Mat image, char *window_name, RNG rng);

int Drawing_Random_Filled_Polygons(Mat image, char *window_name, RNG rng);

int Drawing_Random_Circles(Mat image, char *window_name, RNG rng);

int Displaying_Random_Text(Mat image, char *window_name, RNG rng);

int Displaying_Big_End(Mat image, char *window_name, RNG rng);

const int NUMBER = 100;
const int DELAY = 5;
const int window_width = 900;
const int window_height = 600;
int x_1 = -window_width / 2;
int x_2 = window_width * 3 / 2;
int y_1 = -window_width / 2;
int y_2 = window_width * 3 / 2;

static Scalar randomColor(RNG &rng);

void create_random() {
    int c;
    char window_name[] = "Drawing_2 Tutorial";
    RNG rng(0xFFFFFFFF);
    Mat image = Mat::zeros(window_height, window_width, CV_8UC3);
    imshow(window_name, image);
    waitKey(DELAY);
    c = Drawing_Random_Lines(image, window_name, rng);
    if (c != 0);
    c = Drawing_Random_Rectangles(image, window_name, rng);
    if (c != 0);
    c = Drawing_Random_Ellipses(image, window_name, rng);
    if (c != 0);
    c = Drawing_Random_Polylines(image, window_name, rng);
    if (c != 0);
    c = Drawing_Random_Filled_Polygons(image, window_name, rng);
    if (c != 0);
    c = Drawing_Random_Circles(image, window_name, rng);
    if (c != 0);
    c = Displaying_Random_Text(image, window_name, rng);
    if (c != 0);
    c = Displaying_Big_End(image, window_name, rng);
    if (c != 0);
    waitKey(0);
}

int main() {
    show_hsv();
    create_ten();
    create_audi_imgs();
    create_ellipse();
    create_ellipse_2();

    create_text();

    create_random();
}


void create_ellipse() {
    auto image = (Mat) Mat::zeros(900, 900, CV_8UC3);
    ellipse(image, Point(450, 450), Size(400, 250), 0, 0, 360, Scalar(0, 0, 225), 5, 8);
    ellipse(image, Point(450, 450), Size(250, 110), 90, 0, 360, Scalar(0, 0, 225), 5, 8);
    ellipse(image, Point(450, 320), Size(280, 120), 0, 0, 360, Scalar(0, 0, 225), 5, 8);

    imshow("car sign", image);

    waitKey(0);

}

static Scalar randomColor(RNG &rng) {
    int icolor = (unsigned) rng;
    return Scalar(icolor & 255, (icolor >> 8) & 255, (icolor >> 16) & 255);
}

int Drawing_Random_Lines(Mat image, char *window_name, RNG rng) {
    Point pt1, pt2;
    for (int i = 0; i < NUMBER; i++) {
        pt1.x = rng.uniform(x_1, x_2);
        pt1.y = rng.uniform(y_1, y_2);
        pt2.x = rng.uniform(x_1, x_2);
        pt2.y = rng.uniform(y_1, y_2);
        line(image, pt1, pt2, randomColor(rng), rng.uniform(1, 10), 8);
        imshow(window_name, image);
        if (waitKey(DELAY) >= 0) {
            return -1;
        }
    }
    return 0;
}

int Drawing_Random_Rectangles(Mat image, char *window_name, RNG rng) {
    Point pt1, pt2;
    int lineType = 8;
    int thickness = rng.uniform(-3, 10);
    for (int i = 0; i < NUMBER; i++) {
        pt1.x = rng.uniform(x_1, x_2);
        pt1.y = rng.uniform(y_1, y_2);
        pt2.x = rng.uniform(x_1, x_2);
        pt2.y = rng.uniform(y_1, y_2);
        rectangle(image, pt1, pt2, randomColor(rng), MAX(thickness, -1), lineType);
        imshow(window_name, image);
        if (waitKey(DELAY) >= 0) {
            return -1;
        }
    }
    return 0;
}

int Drawing_Random_Ellipses(Mat image, char *window_name, RNG rng) {
    int lineType = 8;
    for (int i = 0; i < NUMBER; i++) {
        Point center;
        center.x = rng.uniform(x_1, x_2);
        center.y = rng.uniform(y_1, y_2);
        Size axes;
        axes.width = rng.uniform(0, 200);
        axes.height = rng.uniform(0, 200);
        double angle = rng.uniform(0, 180);
        ellipse(image, center, axes, angle, angle - 100, angle + 200,
                randomColor(rng), rng.uniform(-1, 9), lineType);
        imshow(window_name, image);
        if (waitKey(DELAY) >= 0) {
            return -1;
        }
    }
    return 0;
}

int Drawing_Random_Polylines(Mat image, char *window_name, RNG rng) {
    int lineType = 8;
    for (int i = 0; i < NUMBER; i++) {
        Point pt[2][3];
        pt[0][0].x = rng.uniform(x_1, x_2);
        pt[0][0].y = rng.uniform(y_1, y_2);
        pt[0][1].x = rng.uniform(x_1, x_2);
        pt[0][1].y = rng.uniform(y_1, y_2);
        pt[0][2].x = rng.uniform(x_1, x_2);
        pt[0][2].y = rng.uniform(y_1, y_2);
        pt[1][0].x = rng.uniform(x_1, x_2);
        pt[1][0].y = rng.uniform(y_1, y_2);
        pt[1][1].x = rng.uniform(x_1, x_2);
        pt[1][1].y = rng.uniform(y_1, y_2);
        pt[1][2].x = rng.uniform(x_1, x_2);
        pt[1][2].y = rng.uniform(y_1, y_2);
        const Point *ppt[2] = {pt[0], pt[1]};
        int npt[] = {3, 3};
        polylines(image, ppt, npt, 2, true, randomColor(rng), rng.uniform(1, 10), lineType);
        imshow(window_name, image);
        if (waitKey(DELAY) >= 0) {
            return -1;
        }
    }
    return 0;
}

int Drawing_Random_Filled_Polygons(Mat image, char *window_name, RNG rng) {
    int lineType = 8;
    for (int i = 0; i < NUMBER; i++) {
        Point pt[2][3];
        pt[0][0].x = rng.uniform(x_1, x_2);
        pt[0][0].y = rng.uniform(y_1, y_2);
        pt[0][1].x = rng.uniform(x_1, x_2);
        pt[0][1].y = rng.uniform(y_1, y_2);
        pt[0][2].x = rng.uniform(x_1, x_2);
        pt[0][2].y = rng.uniform(y_1, y_2);
        pt[1][0].x = rng.uniform(x_1, x_2);
        pt[1][0].y = rng.uniform(y_1, y_2);
        pt[1][1].x = rng.uniform(x_1, x_2);
        pt[1][1].y = rng.uniform(y_1, y_2);
        pt[1][2].x = rng.uniform(x_1, x_2);
        pt[1][2].y = rng.uniform(y_1, y_2);
        const Point *ppt[2] = {pt[0], pt[1]};
        int npt[] = {3, 3};
        fillPoly(image, ppt, npt, 2, randomColor(rng), lineType);
        imshow(window_name, image);
        if (waitKey(DELAY) >= 0) {
            return -1;
        }
    }
    return 0;
}

int Drawing_Random_Circles(Mat image, char *window_name, RNG rng) {
    int lineType = 8;
    for (int i = 0; i < NUMBER; i++) {
        Point center;
        center.x = rng.uniform(x_1, x_2);
        center.y = rng.uniform(y_1, y_2);
        circle(image, center, rng.uniform(0, 300), randomColor(rng),
               rng.uniform(-1, 9), lineType);
        imshow(window_name, image);
        if (waitKey(DELAY) >= 0) {
            return -1;
        }
    }
    return 0;
}

int Displaying_Random_Text(Mat image, char *window_name, RNG rng) {
    int lineType = 8;
    for (int i = 1; i < NUMBER; i++) {
        Point org;
        org.x = rng.uniform(x_1, x_2);
        org.y = rng.uniform(y_1, y_2);
        putText(image, "Testing text miaomiaole", org, rng.uniform(0, 8),
                rng.uniform(0, 100) * 0.05 + 0.1, randomColor(rng), rng.uniform(1, 10), lineType);
        imshow(window_name, image);
        if (waitKey(DELAY) >= 0) {
            return -1;
        }
    }
    return 0;
}

int Displaying_Big_End(Mat image, char *window_name, RNG) {
    Size textsize = getTextSize("miaomiaole !", FONT_HERSHEY_COMPLEX, 3, 5, 0);
    Point org((window_width - textsize.width) / 2, (window_height - textsize.height) / 2);
    int lineType = 8;
    Mat image2;
    for (int i = 0; i < 255; i += 2) {
        image2 = image - Scalar::all(i);
        putText(image2, "miaomiaole !", org, FONT_HERSHEY_COMPLEX, 3,
                Scalar(i, i, 255), 5, lineType);
        imshow(window_name, image2);
        if (waitKey(DELAY) >= 0) {
            return -1;
        }
    }
    return 0;
}